package gateway.internal.config.yaml;

import gateway.config.Config;
import gateway.internal.config.impl.DefaultConfig;
import gateway.internal.config.impl.DefaultConnectorConfig;
import gateway.internal.config.impl.DefaultFilterConfig;
import gateway.internal.config.impl.DefaultInboundConfig;
import gateway.internal.config.impl.DefaultOutboundConfig;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.List;

/**
 * @author Jin Zheng
 * @since 1.0 2020-09-15
 */
public class YamlConfigLoader
{

	public YamlConfigLoader()
	{
	}

	public Config load()
	{
		return this.load("gateway.yaml");
	}

	public Config load(String file)
	{
		Config config = new DefaultConfig();
		this.load(file, config);
		return config;
	}

	private void load(String file, Config config)
	{
		List<String> imports = null;
		Constructor cons = new Constructor(YamlGatewayConfig.class);
		Yaml yaml = new Yaml(cons);
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		try (InputStream is = classLoader.getResourceAsStream(file))
		{
			YamlGatewayConfig yamlConfig = yaml.loadAs(is, YamlGatewayConfig.class);
			for (YamlRouteConfig route : yamlConfig.getRoutes())
			{
				config.putRouteConfig(route.toConfig());
			}
			for (DefaultConnectorConfig connector : yamlConfig.getConnectors())
			{
				config.putConnectorConfig(connector);
			}
			for (DefaultInboundConfig inbound : yamlConfig.getInbounds())
			{
				config.putInboundConfig(inbound);
			}
			for (DefaultFilterConfig filter : yamlConfig.getFilters())
			{
				config.putFilterConfig(filter);
			}
			for (DefaultOutboundConfig outbound : yamlConfig.getOutbounds())
			{
				config.putOutboundConfig(outbound);
			}
			imports = yamlConfig.getImports();
		}
		catch (IOException e)
		{
			throw new UncheckedIOException(e);
		}
		for (String anImport : imports)
		{
			this.load(anImport, config);
		}
	}

}
